package demo.icanci.proxy;

import demo.icanci.proxy.cglib.AlipayMethodInterceptor;
import demo.icanci.proxy.cglib.CglibUtil;
import demo.icanci.proxy.impl.AliPayToC;
import demo.icanci.proxy.impl.CommonPayment;
import demo.icanci.proxy.impl.ToBPaymentImpl;
import demo.icanci.proxy.impl.ToCPaymentImpl;
import demo.icanci.proxy.jdkproxy.AlipayInvocationHandler;
import demo.icanci.proxy.jdkproxy.JdkDynamicProxyUtil;

/**
 * JDK动态代理 基于Java的反射机制实现 要求业务类必须实现接口
 * CGLIB动态代理ASM机制实现，生成业务类的子类作为代理类
 *
 * JDK原生，在JVM中运行较为可靠 可以平滑升级，不需要引入jar包 只能代理接口
 * CGLIB不是原生，需要引入第三方jar包，升级可能会出现问题 可以代理接口实现类和类
 *
 * SpringAOP的底层机制，就是 CGLIB和JDK动态代理共存
 * 
 * @author icanci
 * @date Created in 2021/03/03 00:38
 * @version 1.0
 */
public class ProxyDemo {
    public static void main(String[] args) {
        cglibProxy();
    }

    private static void staticProxy() {
        ToCPayment toCPayment = new ToCPaymentImpl();
        AliPayToC aliPayToC = new AliPayToC(toCPayment);
        aliPayToC.pay();
    }

    /**
     * JDK 动态代理只能代理接口
     */
    private static void jdkProxy() {
        ToCPaymentImpl toCPayment = new ToCPaymentImpl();
        AlipayInvocationHandler handler = new AlipayInvocationHandler(toCPayment);
        ToCPayment payment = JdkDynamicProxyUtil.newProxyInstance(toCPayment, handler);
        payment.pay();
        ToBPaymentImpl toBPayment = new ToBPaymentImpl();
        AlipayInvocationHandler alipayInvocationHandler = new AlipayInvocationHandler(toBPayment);
        ToBPayment instance = JdkDynamicProxyUtil.newProxyInstance(toBPayment, alipayInvocationHandler);
        instance.pay();
    }

    /**
     * Cglib 可以代理类 也可以代理接口的实现类
     */
    private static void cglibProxy() {
        CommonPayment commonPayment = new CommonPayment();
        AlipayMethodInterceptor alipayMethodInterceptor = new AlipayMethodInterceptor();
        CommonPayment proxy = CglibUtil.createProxy(commonPayment, alipayMethodInterceptor);
        proxy.pay();

        ToCPaymentImpl toCPayment = new ToCPaymentImpl();
        ToCPaymentImpl payment = CglibUtil.createProxy(toCPayment, alipayMethodInterceptor);
        payment.pay();
    }
}
